/*
 * Copyright (C), 2002-2017, 苏宁易购电子商务有限公司
 * FileName: ActivityServiceImpl.java
 * Date:     2017年3月24日 下午6:24:30
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.member.service.impl;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.gson.reflect.TypeToken;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.member.constant.MemberConstants;
import com.suning.sawp.member.dao.ActivityStatisDao;
import com.suning.sawp.member.service.ActivityStatisService;
import com.suning.sawp.member.vo.ActivityCateStatisVo;
import com.suning.sawp.member.vo.ActivityClientStatisVo;
import com.suning.sawp.member.vo.ActivityEmpStatisVo;
import com.suning.sawp.member.vo.ActivityStatisVo;
import com.suning.sawp.member.vo.BrandVo;
import com.suning.sawp.member.vo.CateStatisDetailVo;
import com.suning.sawp.member.vo.ClientStatisDetailVo;
import com.suning.sawp.member.vo.EmpStatisDetailVo;
import com.suning.sawp.service.util.AESUtils;
import com.suning.sawp.service.util.BigDecimalUtils;
import com.suning.sawp.service.util.RedisCacheUtils;

/**
 * 
 * 活动统计服务实现<br>
 *
 * @author 14060886 祝翔龙
 */
@Service
public class ActivityStatisServiceImpl implements ActivityStatisService {

	@Autowired
	private RedisCacheUtils redisClient;
	@Autowired
	private ActivityStatisDao activityStatisDao;

	@Override
	public List<ActivityStatisVo> queryActivityStatisByStore(String storeCode, String startIndex) {
		// 店长外拓统计数据列表缓存
		String key = String.format(CacheKeyConstants.MemberExpand.ACTIVITY_STATIS_4DZ, storeCode);
		String field = startIndex;
		Type type = new TypeToken<List<ActivityStatisVo>>() {
		}.getType();
		List<ActivityStatisVo> result = redisClient.hget(key, field, type);
		if (result != null) {
			return result;
		}

		List<ActivityStatisVo> activityStatisList = activityStatisDao.selectAllActivityStatisByStore(storeCode, Integer.valueOf(startIndex), MemberConstants.PAGE_SIZE);
		if (CollectionUtils.isNotEmpty(activityStatisList)) {
			for (ActivityStatisVo activityStatis : activityStatisList) {
				activityStatis.setRate(getRate(activityStatis.getRealAmount(), activityStatis.getExpectAmount()));
			}
			// 缓存数据
			redisClient.hsetWithMyExpireTime(key, field, activityStatisList, CacheKeyConstants.MemberExpand.HALF_DAY_EXPIRE_TIME);
		} else {
			activityStatisList = new ArrayList<ActivityStatisVo>();
		}
		return activityStatisList;
	}

	@Override
	public Map<String, Object> queryActivityStatisByCate(StoreManDto storeMan, String cateCode, String startIndex) {
		String currentCatecode = cateCode;// 防止sonar报sb错误
		String storeCode = storeMan.getStoreCode();
		String key = null;
		String field = null;
		// cateCode存在的情况下再查缓存 防止串号
		if (StringUtils.isNotEmpty(cateCode)) {
			// 督导外拓统计数据列表缓存
			key = String.format(CacheKeyConstants.MemberExpand.ACTIVITY_STATIS_4DD, storeCode, currentCatecode);
			field = startIndex;
			Type type = new TypeToken<Map<String, Object>>() {
			}.getType();
			Map<String, Object> value = redisClient.hget(key, field, type);
			if (value != null) {
				return value;
			}
		}

		Map<String, Object> result = new HashMap<String, Object>();
		List<Category> categories = storeMan.getCategories();
		// 未维护品类直接返回
		if (CollectionUtils.isEmpty(categories)) {
			return result;
		}

		List<ActivityStatisVo> activityStatisList = new ArrayList<ActivityStatisVo>();
		// 品类编码没传 默认查询出第一个有数据的品类数据 若都没有数据则默认选中第一个品类
		if (StringUtils.isEmpty(currentCatecode)) {
			for (Category category : categories) {
				String categoryCode = category.getCategoryCode();
				activityStatisList = activityStatisDao.selectAllActivityStatisByCate(storeCode, categoryCode, Integer.valueOf(startIndex), MemberConstants.PAGE_SIZE);
				if (CollectionUtils.isNotEmpty(activityStatisList)) {
					currentCatecode = categoryCode;
					break;
				}
			}
			if (CollectionUtils.isEmpty(activityStatisList)) {
				currentCatecode = categories.get(0).getCategoryCode();
			}
		} else {
			activityStatisList = activityStatisDao.selectAllActivityStatisByCate(storeCode, currentCatecode, Integer.valueOf(startIndex), MemberConstants.PAGE_SIZE);
		}
		if (CollectionUtils.isNotEmpty(activityStatisList)) {
			for (ActivityStatisVo activityStatis : activityStatisList) {
				activityStatis.setRate(getRate(activityStatis.getRealAmount(), activityStatis.getExpectAmount()));
			}
		}

		result.put("cates", generateCategorys(categories, currentCatecode));
		result.put("activityStatisList", activityStatisList);
		if (StringUtils.isNotEmpty(cateCode) && CollectionUtils.isNotEmpty(activityStatisList)) {
			// 缓存数据
			redisClient.hsetWithMyExpireTime(key, field, result, CacheKeyConstants.MemberExpand.HALF_DAY_EXPIRE_TIME);
		}
		return result;
	}

	@Override
	public List<ActivityStatisVo> queryActivityStatisByEmp(String storeCode, String employeeId, String startIndex) {
		// 店员外拓统计数据列表缓存
		String key = String.format(CacheKeyConstants.MemberExpand.ACTIVITY_STATIS_4DY, storeCode, employeeId);
		String field = startIndex;
		Type type = new TypeToken<List<ActivityStatisVo>>() {
		}.getType();
		List<ActivityStatisVo> result = redisClient.hget(key, field, type);
		if (result != null) {
			return result;
		}

		List<ActivityStatisVo> activityStatisList = activityStatisDao.selectAllActivityStatisByEmp(storeCode, employeeId, Integer.valueOf(startIndex), MemberConstants.PAGE_SIZE);
		if (CollectionUtils.isNotEmpty(activityStatisList)) {
			for (ActivityStatisVo activityStatis : activityStatisList) {
				activityStatis.setRate(getRate(activityStatis.getRealAmount(), activityStatis.getExpectAmount()));
			}
			// 缓存数据
			redisClient.hsetWithMyExpireTime(key, field, activityStatisList, CacheKeyConstants.MemberExpand.HALF_DAY_EXPIRE_TIME);
		} else {
			activityStatisList = new ArrayList<ActivityStatisVo>();
		}
		return activityStatisList;
	}

	@Override
	public CateStatisDetailVo queryCateStatisDetailByStore(String storeCode, String activityId, String source, String mode) {
		// 某外拓活动统计详情缓存
		String key = String.format(CacheKeyConstants.MemberExpand.ACTIVITY_STATIS_STORE, storeCode, activityId);
		String field = source + "_" + mode;
		Type type = new TypeToken<CateStatisDetailVo>() {
		}.getType();
		CateStatisDetailVo result = redisClient.hget(key, field, type);
		if (result != null) {
			return result;
		}

		result = new CateStatisDetailVo();
		ActivityStatisVo activityStatis = activityStatisDao.selectActivityStatisByStore(storeCode, activityId, source, mode);
		if (null != activityStatis) {
			activityStatis.setRate(getRate(activityStatis.getRealAmount(), activityStatis.getExpectAmount()));
		}
		result.setStatistic(activityStatis);
		List<ActivityCateStatisVo> cateStatisList = activityStatisDao.selectCateStatisByStore(storeCode, activityId, source, mode);
		if (CollectionUtils.isNotEmpty(cateStatisList)) {
			for (ActivityCateStatisVo activityCateStatis : cateStatisList) {
				activityCateStatis.setRate(getRate(activityCateStatis.getRealAmount(), activityCateStatis.getExpectAmount()));
				activityCateStatis.setCateName(ConfigConstants.DEFAULT_CATE_MAP.get(activityCateStatis.getCateCode()));
			}
		} else {
			cateStatisList = new ArrayList<ActivityCateStatisVo>();
		}
		result.setCateList(cateStatisList);
		// 缓存数据
		redisClient.hsetWithMyExpireTime(key, field, result, CacheKeyConstants.MemberExpand.HALF_DAY_EXPIRE_TIME);
		return result;
	}

	@Override
	public EmpStatisDetailVo queryEmpStatisDetailByCate(String storeCode, String activityId, String cateCode, String source, String mode) {
		// 某外拓活动品类统计详情缓存
		String key = String.format(CacheKeyConstants.MemberExpand.ACTIVITY_STATIS_CATE, storeCode, activityId, cateCode);
		String field = source + "_" + mode;
		Type type = new TypeToken<EmpStatisDetailVo>() {
		}.getType();
		EmpStatisDetailVo result = redisClient.hget(key, field, type);
		if (result != null) {
			return result;
		}

		result = new EmpStatisDetailVo();
		ActivityCateStatisVo activityCateStatis = activityStatisDao.selectActivityStatisByCate(storeCode, activityId, cateCode, source, mode);
		if (null != activityCateStatis) {
			activityCateStatis.setRate(getRate(activityCateStatis.getRealAmount(), activityCateStatis.getExpectAmount()));
			activityCateStatis.setCateCode(cateCode);
			activityCateStatis.setCateName(ConfigConstants.DEFAULT_CATE_MAP.get(activityCateStatis.getCateCode()));
		}
		result.setStatistic(activityCateStatis);
		List<ActivityEmpStatisVo> empStatisList = activityStatisDao.selectEmpStatisByCate(storeCode, activityId, cateCode, source, mode);
		if (CollectionUtils.isNotEmpty(empStatisList)) {
			for (ActivityEmpStatisVo activityEmpStatis : empStatisList) {
				activityEmpStatis.setRate(getRate(activityEmpStatis.getRealAmount(), activityEmpStatis.getExpectAmount()));
			}
		} else {
			empStatisList = new ArrayList<ActivityEmpStatisVo>();
		}
		result.setEmployeeList(empStatisList);
		// 缓存数据
		redisClient.hsetWithMyExpireTime(key, field, result, CacheKeyConstants.MemberExpand.HALF_DAY_EXPIRE_TIME);
		return result;
	}

	@Override
	public ClientStatisDetailVo queryClientStatisDetailByEmp(String storeCode, String activityId, String cateCode, String employeeId, 
	        String source, String mode, String startIndex) {
		// 某外拓活动客户统计详情缓存
		String key = String.format(CacheKeyConstants.MemberExpand.ACTIVITY_STATIS_EMP, storeCode, activityId, employeeId);
		String field = source + "_" + mode + "_" + startIndex;
		Type type = new TypeToken<ClientStatisDetailVo>() {
		}.getType();
		ClientStatisDetailVo result = redisClient.hget(key, field, type);
		if (result != null) {
			return result;
		}
	    result = new ClientStatisDetailVo();
		ActivityStatisVo activityStatis = activityStatisDao.selectActivityStatisByEmp(storeCode, activityId, cateCode, employeeId, source, mode);
		if (null != activityStatis) {
			activityStatis.setRate(getRate(activityStatis.getRealAmount(), activityStatis.getExpectAmount()));
		}
		result.setStatistic(activityStatis);
		List<ActivityClientStatisVo> clientStatisList = activityStatisDao.selectClientStatisByEmp(storeCode, activityId, cateCode, 
		        employeeId, source, mode, Integer.valueOf(startIndex), MemberConstants.PAGE_SIZE);
		result.setCustomerList(handleCateBrand(clientStatisList));
		// 缓存数据
		redisClient.hsetWithMyExpireTime(key, field, result, CacheKeyConstants.MemberExpand.HALF_DAY_EXPIRE_TIME);
		return result;
	}

	// 生成品类数据, 返回给前端
	private List<Map<String, String>> generateCategorys(List<Category> categories, String cateCode) {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		for (int i = 0; i < categories.size(); i++) {
			Map<String, String> map = new HashMap<String, String>(3);
			String cCode = categories.get(i).getCategoryCode();
			map.put("cateCode", cCode);
			map.put("cateName", categories.get(i).getCategoryName());
			map.put("checked", cateCode.equals(cCode) ? "1" : "0"); // 设置默认选中值
			list.add(map);
		}
		return list;
	}

	private String getRate(String realAmount, String expectAmount) {
		if (StringUtils.isEmpty(realAmount) || StringUtils.isEmpty(expectAmount)) {
			return String.valueOf(BigDecimal.ZERO) + "%";
		}
		return String.valueOf(BigDecimalUtils.calPercent(new BigDecimal(realAmount), new BigDecimal(expectAmount)));
	}

	/**
	 * 
	 * 功能描述: 处理品类品牌对应关系<br>
	 *
	 * @param clientStatisList
	 * @return
	 */
	private List<ActivityClientStatisVo> handleCateBrand(List<ActivityClientStatisVo> clientStatisList) {
		if (CollectionUtils.isNotEmpty(clientStatisList)) {
			Map<String, ActivityClientStatisVo> temp = new HashMap<String, ActivityClientStatisVo>();
			for (ActivityClientStatisVo clientStatis : clientStatisList) {
				clientStatis.setInMobile(getInMobile(clientStatis.getMobile())); // 脱敏
				clientStatis.setMobile(getEncryptPhone(clientStatis.getMobile())); // 加密
				String custId = clientStatis.getCustId();
				ActivityClientStatisVo clientStatisInMap = temp.get(custId);
				if (null == clientStatisInMap) {
				    if(clientStatis.getAmount().compareTo(BigDecimal.ZERO) > 0){
				        List<BrandVo> brandList = new ArrayList<BrandVo>();
	                    brandList.add(newBrand(clientStatis.getCateCode(), clientStatis.getBrand()));
	                    clientStatis.setBrandList(brandList);
				    }
					temp.put(custId, clientStatis);
				} else {
					clientStatisInMap.setAmount(clientStatisInMap.getAmount().add(clientStatis.getAmount()));
					List<BrandVo> brandList = clientStatisInMap.getBrandList();
					brandList.add(newBrand(clientStatis.getCateCode(), clientStatis.getBrand()));
					clientStatisInMap.setBrandList(brandList);
					temp.put(custId, clientStatisInMap);
				}
			}
			Collection<ActivityClientStatisVo> values = temp.values();
			clientStatisList = new ArrayList<ActivityClientStatisVo>(values);
		}
		return clientStatisList;
	}

	private BrandVo newBrand(String cateCode, String brandName) {
		BrandVo brand = new BrandVo();
		brand.setCateName(ConfigConstants.DEFAULT_CATE_MAP.get(cateCode));
		brand.setBrandName(brandName);
		return brand;
	}

	private String getInMobile(String mobile) {
		if (StringUtils.isNotEmpty(mobile)) {
			return mobile.substring(0, 3) + "******" + mobile.substring(9, mobile.length());
		}
		return mobile;
	}

	private String getEncryptPhone(String phone) {
		if (StringUtils.isNotEmpty(phone)) {
			return AESUtils.encrypt(phone, ConfigConstants.AES_KEY);
		}
		return StringUtils.EMPTY;
	}

}
